package commons;

import gui.mainView.UIView;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.Serializable;

import player.Player;


import upload.Request;

/**
 * The Media class is used to create new media and manage them in a object of type MediaList
 * @author 
 */
public class Media implements Serializable{

	private String mediaName;
	private User user;
	private String path;
	private MetaData metadata;
	private String toString;
	private boolean downloadFinished;


	/**
	 * Constructor of the class
	 * @param mediaName : the name of the media
	 * @param path : the path of the media
	 * @param user : the user who add this media
	 * @param metadata : the metadata of the media
	 */
	public Media(String mediaName, String path, User mediaUser, boolean downloadFinished){
		this.mediaName=mediaName;
		this.path=path+mediaName;
		this.user=mediaUser;
		this.downloadFinished=downloadFinished;
		this.metadata=Player.metaData(path,this.downloadFinished);
		this.toString=mediaName;
	}
	
	/**
	 * Get the media's name
	 * @return the name of the media
	 */
	public String getMediaName() {
		return mediaName;
	}

	/**
	 * Set of the media's name
	 * @param name : the new name of the media
	 */
	public void setMediaName(String mediaName) {
		this.mediaName = mediaName;
	}

	/**
	 * Get the user who add the media
	 * @return an object type user
	 */
	public User getUser() {
		return user;
	}

	/**
	 * Set of the media's path
	 * @param path : the new path of the media
	 */
	public void setPath(String path) {
		this.path = path;
	}
	
	/**
	 * Get the media's name
	 * @return the name of the media
	 */
	public String getPath() {
		return path;
	}
	
	/**
	 * Get the media's title
	 * @return the title of the media
	 */
	public String getTitle(){
		return metadata.getTitle();
	}
	
	/**
	 * Get the media's artist
	 * @return the artist of the media
	 */
	public String getArtist(){
		return metadata.getArtist();
	}
	
	/**
	 * Get the media's album
	 * @return the album of the media
	 */
	public String getAlbum(){
		return metadata.getAlbum();
	}
	
	/**
	 * Get the media's duration
	 * @return the duration of the media
	 */
	public String getDuration(){
		return metadata.getDuration();
	}
	
	
	public void setDownloadFinished(boolean bool){
		this.downloadFinished=bool;
		if(this.downloadFinished){
			this.metadata=Player.metaData(this.path,this.downloadFinished);
			this.toString=setToString();
			if(Manager.getInstance().getMediaPlaying()==this){
				Manager.getInstance().updateIface(UIView.Update_InfoPan);
			}
		}
	}
	
	
	public boolean isDownloadFinished(){
		return this.downloadFinished;
	}
	
	
	private String setToString(){
		if(this.getTitle().equals("")){
			if(this.mediaName.length()>16){
				return this.getMediaName().substring(0, 15)+", "+this.user.getName()+" ("+this.getDuration()+")";
			}
			return this.getMediaName()+", "+this.user.getName()+" ("+this.getDuration()+")";
		}
		else{
			return this.getTitle()+" - "+this.getArtist()+", "+this.user.getName()+" ("+this.getDuration()+")";
		}
	}
	
	
	/**
	 * Creates a Media from a given URL (Youtube, Dailymotion, etc)
	 * @param url The link of the video
	 * @param user The user that uploaded the file
	 * @param The path where the file is stored
	 * @return The Media created or null if we were unable to download the media
	 */
	public static Media createMediaFromLink(String url, User user, String path) {
		try {
			ProcessBuilder pb0 = new ProcessBuilder("/bin/sh", "-c","filename=$(youtube-dl --get-filename "+url+") ; echo $filename");
			pb0.redirectErrorStream(true);
			Process p = pb0.start();
			BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
			String filename = reader.readLine();
			if (filename.contains("Falling back on generic information extractor") || filename.contains("Traceback (most recent call")
					|| filename.contains("ERROR:") || filename.contains("Youtube said") || filename.contains("WARNING:"))
				return null;
			filename = Request.renameFileIfExists(filename, Paths.AIRPI_UPLOADED_FILES);
			ProcessBuilder pb1 = new ProcessBuilder("/bin/sh", "-c","cd \""+Paths.AIRPI_UPLOADED_FILES+"\" ; youtube-dl --output \""+filename+"\" -w --no-part "+url);
			pb1.start();
			System.out.println("Receiving: "+filename+" (waiting 20s)");
			try{Thread.sleep(20000);}catch(Exception e){/*ignore*/}
			String newName = filename.substring(0,filename.length()-16);
			System.out.println("Received: "+newName);
			return new Media(newName, path, user, true);
		}
		catch (Exception e) {
			return null;
		}
	}
	
	
	@Override
	public String toString(){
		return toString;
	}
	
	public boolean equals(Media otherMedia){
		return (this.mediaName.equals(otherMedia.mediaName) && this.path.equals(otherMedia.path) && this.user.equals(otherMedia.user));
	}
}